package juego.tests;

import java.util.ArrayList;

import juego.modelo.Bonus;
import juego.modelo.Camino;
import juego.modelo.Comida;
import juego.modelo.Fantasma;
import juego.modelo.MapaFactory;
import juego.modelo.Movimiento;
import juego.modelo.Pacman;
import juego.modelo.Punto;
import juego.modelo.Resultados;
import juego.modelo.Tablero;
import junit.framework.TestCase;

public class TableroTest extends TestCase {

	private Tablero tablero = Tablero.getInstance();
	private Punto punto = new Punto(280,460);// posicion inicial en el mapa1 de pacman es (280,460)

	public void testGetInstance() {
		try {
			tablero = Tablero.getInstance();
			assertFalse(tablero == null);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testCrearJuego() {
		try {
			this.tablero.crearJuego(1);
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testCrearJuegoError() {
		try {
			this.tablero.crearJuego(-10);
			fail();
		} catch (IllegalArgumentException ex) {
			assertTrue(true);
		}
	}
	
	public void testGetPuntaje() {
		try {
			this.tablero.crearJuego(1);
			int puntaje = this.tablero.getPuntaje();
			assertEquals(puntaje,0);
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testSetPuntaje() {
		try {
			this.tablero.crearJuego(1);
			this.tablero.setPuntaje(100);
			int puntaje = this.tablero.getPuntaje();
			assertEquals(puntaje,100);
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}


	public void testSumarPuntos() {
		try {
			this.tablero.crearJuego(1);
			this.tablero.sumarPuntos(100);
			assertTrue(true);
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testSumarPuntosNoSuma() {
		try {
			this.tablero.crearJuego(1);
			this.tablero.sumarPuntos(-100);
			assertTrue(true);
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testGetProximoPunto() {
		try {
			this.tablero.crearJuego(1);
			Punto otroPunto = this.tablero.getProximoPunto(punto,
					Movimiento.IZQUIERDA);
			assertEquals(punto.getPuntoX() - 1, otroPunto.getPuntoX());
			assertEquals(punto.getPuntoY(), otroPunto.getPuntoY());
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testGetProximoPunto2() {// no puede moverse arriba, se queda en
										// el mismo punto
		try {
			this.tablero.crearJuego(1);
			Punto otroPunto = this.tablero.getProximoPunto(punto,
					Movimiento.ARRIBA);
			assertEquals(punto.getPuntoX(), otroPunto.getPuntoX());
			assertEquals(punto.getPuntoY(), otroPunto.getPuntoY());
		} catch (IllegalArgumentException ex) {
			fail();
		}
	}

	public void testEstadoDelJuego() {
		try {
			Tablero tablero = Tablero.getInstance();
			tablero.crearJuego(1);
			assertEquals(tablero.estadoDelJuego(),true);
		} catch (IllegalArgumentException e) {
			fail();
		}
	}
	public void testCerrarJuego() {
		try {
			Tablero tablero = Tablero.getInstance();
			tablero.crearJuego(1);
			tablero.cerrarJuego();
			assertEquals(tablero.estadoDelJuego(),false);
		} catch (IllegalArgumentException e) {
			fail();
		}
	}

	public void testDesaparecerPersonajes() {
		try {
			this.tablero.crearJuego(1);
			this.tablero.desaparecerPersonajes();
			Pacman pacman = tablero.getPacman();
			assertEquals (pacman.getVidas(),2);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetObjetoEnPosicion() {
		this.tablero.crearJuego(1);
		Punto unaPosicion = new Punto(100, 100);
		Object unObjeto = null;
		try {
			unObjeto = this.tablero.getObjetoEnPosicion(unaPosicion);
			assertTrue(unObjeto != null);
		} catch (Exception ex) {
			fail();
		}
	}
	
	public void testGetObjetoEnPosicionFueraDeRango() {
		this.tablero.crearJuego(1);
		Punto unaPosicion = new Punto(2000, -500);
		try {
			Object objeto = this.tablero.getObjetoEnPosicion(unaPosicion);
			fail();
		} catch (IndexOutOfBoundsException ex) {
			assertTrue(true);
		}
	}

	public void testBorrarComida() {
		this.tablero.crearJuego(1);
		Punto unaPosicion = new Punto(1, 4);
		this.tablero.borrarComida(unaPosicion);
		assertTrue(this.tablero.getObjetoEnPosicion(unaPosicion) == null);
	}

	public void testBorrarComidaNoBorra() {
		this.tablero.crearJuego(1);
		Punto unaPosicion = new Punto(5, 0); // posicion de una pared.
		try {
			this.tablero.borrarComida(unaPosicion);
			fail();
		} catch (IndexOutOfBoundsException ex) {
			assertTrue(true);
		}
	}

	public void testBorrarPuntoPoder() {
		Punto posicion = new Punto(1, 5); // Posicion de un punto de poder.
		try {
			this.tablero.crearJuego(1);
			this.tablero.borrarPuntoPoder(posicion);
			assertTrue(this.tablero.getObjetoEnPosicion(posicion) == null);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetParedes() {
		try {
			this.tablero.crearJuego(1);
			Punto[][] paredes = this.tablero.getParedes();
			assertTrue(paredes[0][0] != null);//esquina superior izquierda
			assertTrue(paredes[27][30] != null);//esquina inferios derecha
		} catch (Exception ex) {
			fail();
		}
	}
	

	public void testSetParedes() {
		try {
			Punto unPunto = new Punto(1, 1);
			Punto[][] pared = new Punto[10][10];
			pared[1][1] = unPunto;
			this.tablero.setParedes(pared);
			Punto[][] miPared = tablero.getParedes();
			assert (miPared[1][1] == unPunto);
		} catch (Exception ex) {
			fail();
		}
	}
	public void testGetTamanoMapa() {
		try {
			this.tablero.crearJuego(1);
			assertEquals (this.tablero.getTamanoMapa(),200);
		} catch (Exception ex) {
			fail();
		}
	}
	public void testSetTamanoMapa() {
		try {
			this.tablero.crearJuego(1);
			this.tablero.setTamanoMapa(200);
			assertEquals (this.tablero.getTamanoMapa(),200);
		} catch (Exception ex) {
			fail();
		}
	}
	
	public void testSetTamanoMapaNoSetea(){
		try{
			this.tablero.crearJuego(1);
			this.tablero.setTamanoMapa(-100);
		}catch ( IllegalArgumentException ex ){
			fail();
		}
	}
	public void testGetCaminos() {
		try {
			this.tablero.crearJuego(1);
			Punto[][] caminos = this.tablero.getCaminos();
			assertTrue(caminos[1][1] != null);//esquina superior izquierda
			assertTrue(caminos[26][29] != null);//esquina inferios derecha
		} catch (Exception ex) {
			fail();
		}
	}

	public void testSetCaminos() {
		try {
			punto = new Punto(1, 1);
			Punto[][] caminos = new Punto[10][10];
			caminos[1][1] = punto;
			this.tablero.setCaminos(caminos);
			Punto[][] miCamino = tablero.getCaminos();
			assert (miCamino[1][1] == punto);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetComidas() {
		try {
			this.tablero.crearJuego(1);
			Comida[][] comidas = this.tablero.getComidas();
			assertTrue(comidas[1][1] != null);// esquina superior izquierda
			assertTrue(comidas[26][29] != null);// esquina inferios derecha
		} catch (Exception ex) {
			fail();
		}
	}
	
	public void testSetComidas() {
		try {
			punto = new Punto(1, 1);
			Punto[][] comida = new Punto[10][10];
			comida[1][1] = punto;
			this.tablero.setCaminos(comida);
			Comida[][] miCamino = tablero.getComidas();
			assert (miCamino[1][1] != null);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetCantidadPuntosComunes() {
		try {
			this.tablero.crearJuego(1);
			assertEquals(this.tablero.getCantidadPuntosComunes(), 247);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testSetCantidadPuntosComunes() {
		try {
			this.tablero.crearJuego(1);
			tablero.setCantidadPuntosComunes(200);
			assertEquals(this.tablero.getCantidadPuntosComunes(), 200);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetCantidadFantasmas() {
		this.tablero.crearJuego(1);
		int cantidad = this.tablero.getCantidadFantasmas();
		assertEquals(cantidad, 4);
	}

	public void testSetCantidadFantasmas() {
		this.tablero.crearJuego(1);
		try {
			this.tablero.setCantidadFantasmas(20);
			assertEquals(20, this.tablero.getCantidadFantasmas());
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetPosicionInicialPacman() {
		this.tablero.crearJuego(1);
		Punto posision = this.tablero.getPosicionInicialPacman();
		assert (posision == punto);
	}

	public void testSetPosicionInicialPacman() {
		this.tablero.crearJuego(1);
		Punto otroPunto = new Punto(1, 1);
		tablero.setPosicionInicialPacman(otroPunto);
		Punto posision = this.tablero.getPosicionInicialPacman();
		assert (posision == otroPunto);
	}


	public void testGetPosicionInicialFantasmas() {
		this.tablero.crearJuego(1);
		Punto otroPunto = new Punto(280, 280);
		Punto posision = this.tablero.getPosicionInicialFantasmas();
		assert (posision == otroPunto);
	}

	public void testSetPosicionInicialFantasma() {
		this.tablero.crearJuego(1);
		Punto otroPunto = new Punto(1, 1);
		tablero.setPosicionInicialFantasma(otroPunto);
		Punto posision = this.tablero.getPosicionInicialPacman();
		assert (posision == otroPunto);
	}


	public void testGetDistanciaEntreComida() {
		this.tablero.crearJuego(1);
		int cantidad = this.tablero.getDistanciaEntreComida();
		assertEquals(cantidad, 20);
	}

	public void testGetPuntosPoder() {
		this.tablero.crearJuego(1);
		try {
			ArrayList<Punto> puntosDePoder = this.tablero.getPuntosPoder();
			Punto punto = puntosDePoder.get(0);
			assertEquals(punto.getPuntoX(), 1);
			assertEquals(punto.getPuntoY(), 5);

			punto = puntosDePoder.get(1);
			assertEquals(punto.getPuntoX(), 26);
			assertEquals(punto.getPuntoY(), 5);

			punto = puntosDePoder.get(2);
			assertEquals(punto.getPuntoX(), 1);
			assertEquals(punto.getPuntoY(), 23);

			punto = puntosDePoder.get(3);
			assertEquals(punto.getPuntoX(), 26);
			assertEquals(punto.getPuntoY(), 23);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testSetPuntosPoder() {
		try {
			punto = new Punto(1, 1);
			ArrayList<Punto> puntosDePoder = new ArrayList(10);
			puntosDePoder.add(punto);
			this.tablero.setPuntosPoder(puntosDePoder);
			ArrayList<Punto> miPuntosDePoder = tablero.getPuntosPoder();
			assert (miPuntosDePoder.get(0) == punto);
		} catch (Exception ex) {
			fail();
		}
	}

	public void testGetMapa() {
		this.tablero.crearJuego(1);
		MapaFactory mapa = this.tablero.getMapa();
		assert (mapa != null);
	}

	public void testGetPacman() {
		this.tablero.crearJuego(1);
		Pacman pacman = this.tablero.getPacman();
		assert (pacman != null);
	}

	public void testGetFantasmas() {
		this.tablero.crearJuego(1);
		ArrayList<Fantasma> fantasmas = tablero.getFantasmas();
		assertEquals(fantasmas.size(), 4);
	}

	public void testGetBonus() {
		this.tablero.crearJuego(1);
		Bonus bonus = this.tablero.getBonus();
		assert (bonus != null);
	}

	public void testGetAngulo() {
		this.tablero.crearJuego(1);
		double angulo = this.tablero.getAngulo();
		assertEquals(angulo, 3.14);
	}

	public void testGetPosicionPacman() {
		this.tablero.crearJuego(1);
		Punto posicion = this.tablero.getPosicionInicialPacman();
		assert (posicion == punto);
	}


	public void testGetResultados() {
		this.tablero.crearJuego(1);
		Resultados resultados = this.tablero.getResultados();
		assert (resultados != null);
	}
}
